using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Christian.Helle.PocketNews.PocketPC.Controls;
using Christian.Helle.PocketNews.PocketPC.NewsProtocol;
using Christian.Helle.PocketNews.PocketPC.Data;
using System.Threading;

namespace Christian.Helle.PocketNews.PocketPC
{
	public partial class frmNewsgroups : FormEx
	{
		private Thread thread;
		private delegate void UpdateList(string[] groups);
		private delegate void UpdateStatus(string status);
		private UpdateStatus UpdateStatusDelegate;
		private UpdateList UpdateListDelegate;

		public frmNewsgroups()
		{
			InitializeComponent();
			LoadNewsgroups();
		}

		private void LoadNewsgroups()
		{
			LoadFromCache();

			if (lvNewsgroups.Items.Count > 0)
			{
				DialogResult dr = MessageBox.Show(
					"Do you wish to update the list of newsgroups?",
					"Newsgroups",
					MessageBoxButtons.YesNo,
					MessageBoxIcon.Question,
					MessageBoxDefaultButton.Button1);

				if (dr == DialogResult.Yes)
				{
					UpdateStatusBar("Verifying connection");
					if (Connection.VerifyConnection())
					{
						LoadFromInternet();
					}
				} 
			}
			else
			{
				UpdateStatusBar("Verifying connection");
				if (Connection.VerifyConnection())
				{
					LoadFromInternet();
				}
			}
		}

		private void LoadFromCache()
		{
			UpdateStatusBar("Loading Cached Newsgroups");

			using (WaitCursor wait = new WaitCursor()) {
				PopulateList(DataAccess.Instance.GetCachedNewsgroups());
			}
		}

		private void LoadFromInternet()
		{
			UpdateListDelegate = new UpdateList(PopulateList);
			UpdateStatusDelegate = new UpdateStatus(UpdateStatusBar);

			if (thread == null) {
				thread = new Thread(new ThreadStart(LoadFromInternetWorker));
				thread.Name = "LoadFromInternet Worker";
				thread.IsBackground = true;
				thread.Start(); 
			}
		}

		private void LoadFromInternetWorker()
		{
			try {
				using (WaitCursor wait = new WaitCursor()) {
					string[] groups = null;

					using (Nntp nntp = new Nntp()) {
						Invoke(
							UpdateStatusDelegate,
							new object[] { "Connecting..." });

						nntp.Connect("msnews.microsoft.com");

						if (!nntp.IsConnected) {
							Invoke(
								UpdateStatusDelegate,
								new object[] { "Unable to Connect" });

							return;
						} else {
							Invoke(
								UpdateStatusDelegate,
								new object[] { "Connected" });
						}
						
						Invoke(
							UpdateStatusDelegate,
							new object[] { "Retrieving List..." });

						groups = nntp.ListGroup();
					}

					if (groups != null) {
						Invoke(
							UpdateStatusDelegate,
							new object[] { "Updating Cache" });

						DataAccess.Instance.UpdateNewsgroupCache(groups);

						Invoke(
							UpdateListDelegate,
							new object[] { groups }); 
					}
				}
			}
			catch (ThreadAbortException) { }
			finally {
				thread = null;
			}
		}

		private void PopulateList(string[] groups)
		{
			lvNewsgroups.Items.Clear();

			if (groups == null || groups.Length == 0) {
				UpdateStatusBar("Loaded 0 Newsgroups");
				return;
			}

			using (WaitCursor wait = new WaitCursor()) {
				UpdateStatusBar("Loading List");

				try {
					lvNewsgroups.BeginUpdate();

					for (int i = 0; i < groups.Length; i++) {
						//ListViewItem item = new ListViewItem(groups[i]);
						//item.Tag = groups[i];

						//lvNewsgroups.Items.Add(item);
						lvNewsgroups.Items.Add(groups[i]);
					}
				}
				finally {
					lvNewsgroups.EndUpdate();
				}

				//lvNewsgroups.Items.Clear();
				//lvNewsgroups.DataSource = groups;

				UpdateStatusBar(
					string.Format(
						"Loaded {0} Newsgroups", 
						groups.Length));
			}
		}

		private void UpdateStatusBar(string status)
		{
			sbStatus.Text = status;
			sbStatus.Update();
		}

		private void Cancel_Click(object sender, EventArgs e)
		{
			if (thread != null) {
				thread.Abort();
			} else {
				DialogResult = DialogResult.Cancel;
				Close();
			}
		}

		private void frmNewsgroups_Closing(object sender, CancelEventArgs e)
		{
			if (thread != null) {
				thread.Abort();
			}
		}

		private void btnSearch_Click(object sender, EventArgs e)
		{
			SearchDatabase();
		}

		private void SearchDatabase()
		{
			using (WaitCursor wait = new WaitCursor()) {
				if (string.IsNullOrEmpty(tbSearchParam.Text)) {
					PopulateList(DataAccess.Instance.GetCachedNewsgroups());
				} else {
					PopulateList(
						DataAccess.Instance.SearchNewsgroups(tbSearchParam.Text));
				}
			}
		}

		private void menuSubscribe_Click(object sender, EventArgs e)
		{
			//if (lvNewsgroups.SelectedIndices[0] == -1) {
			//  return;
			//}

			//ListViewItem lvi = lvNewsgroups.FocusedItem;
			//string group = lvi.Tag as string;

			if (lvNewsgroups.SelectedIndex == -1) {
				return;
			}

			string group = lvNewsgroups.SelectedItem as string;

			if (!string.IsNullOrEmpty(group)) {
				DataAccess.Instance.SubscribeToGroup(group);
				DataAccess.Instance.CreateNewsgroupTable(group);
				Configuration.CurrentNewsgroup = group;
			}

			DialogResult = DialogResult.OK;
			Close();
		}

		private void tbSearchParam_KeyDown(object sender, KeyEventArgs e)
		{
			if (e.KeyCode == Keys.Enter) {
				SearchDatabase();
			}
		}

		private void tbSearchParam_KeyPress(object sender, KeyPressEventArgs e)
		{
			if (e.KeyChar == 13) {
				SearchDatabase();
			}
		}
	}
}